﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

using UnityNetwork;

public class SocketManager : MonoSingleton<SocketManager>
{
    public enum GameMessageId
    {
        NetMsg = 101,
    }


    private GameNetHandler gameNetHandler = null;
    private XLua.LuaTable luaEnv;
    private Action<XLua.LuaTable> onConnected = null;
    private Action<XLua.LuaTable> onConnectFail = null;
    private Action<XLua.LuaTable> onDisconnect = null;
    private Action<XLua.LuaTable, int, byte[], int> onRecive = null;

    private bool isConnected = false;

    public void SetLuaEnv(XLua.LuaTable luaEnv)
    {
        this.luaEnv = luaEnv;
        luaEnv.Get("onConnected", out onConnected);
        luaEnv.Get("onConnectFail", out onConnectFail);
        luaEnv.Get("onDisconnect", out onDisconnect);
        luaEnv.Get("onRecive", out onRecive);
    }

    private void Awake()
    {
        gameNetHandler = new GameNetHandler();
        gameNetHandler.AddHandler((int)TCPPeer.MessageID.OnConnected, OnConnectedServer);
        gameNetHandler.AddHandler((int)TCPPeer.MessageID.OnConnectFail, OnConnectedServerFail);
        gameNetHandler.AddHandler((int)TCPPeer.MessageID.OnDisconnect, OnDisconnectServer);
        gameNetHandler.AddHandler((int)GameMessageId.NetMsg, OnReciveMsg);
    }

    // Start is called before the first frame update
    void Start()
    {
    }

    public void ConnectServer(string ip, int port)
    {
        gameNetHandler.ConnectServer(ip, port);
    }

    void OnConnectedServer(Packet packet)
    {
        isConnected = true;
        if (onConnected != null)
        {
            onConnected(luaEnv);
        }
    }

    void OnConnectedServerFail(Packet packet)
    {
        isConnected = false;
        if (onConnectFail != null)
        {
            onConnectFail(luaEnv);
        }
    }

    void OnDisconnectServer(Packet packet)
    {
        isConnected = false;
        if (onDisconnect != null)
        {
            onDisconnect(luaEnv);
        }
    }

    void OnReciveMsg(Packet packet)
    {
        byte[] idBytes = new byte[2];
        byte[] bodyBuffer = new byte[packet.bodyLength - 2];
        Buffer.BlockCopy(packet.buffer, 4, idBytes, 0, 2);
        Buffer.BlockCopy(packet.buffer, 6, bodyBuffer, 0, bodyBuffer.Length);
        short msgId = BitConverter.ToInt16(idBytes, 0);
        if (onRecive != null)
        {
            onRecive(luaEnv, msgId, bodyBuffer, bodyBuffer.Length);
        }
    }

    public void Send(short id, byte[] buffer)
    {
        if (isConnected)
        {
            gameNetHandler.Send(id, buffer);
        }
    }

    private void Update()
    {
        if (gameNetHandler != null)
            gameNetHandler.ProcessPackets();
    }

    private void OnDestroy()
    {
        isConnected = false;
    }

    public void Close()
    {
        isConnected = false;
        gameNetHandler.Close();
    }

    void OnApplicationQuit()
    {
        Close();
    }
}
